package pruebas;

import java.util.LinkedList;
import java.util.NoSuchElementException;
import modelo.auto.*;
import modelo.excepciones.InvalidMaxMarchaCajaException;
import modelo.excepciones.UnableToAddElementToListException;
import modelo.excepciones.UnableToRemoveElementFromListException;
//import excepciones.*;
import junit.framework.*;

public class TestAuto extends TestCase {
	private Auto auto;
	
	protected void setUp() throws Exception {
		auto = new Auto();
	}

	protected void tearDown() throws Exception {
		super.tearDown();
	}


	public void testAcelerar() {
		
		auto.acelerar();		
		auto.update(400);

		assertEquals(0.023, auto.getAceleracion(), 0.1); //aca chekea que se haya modificado la aceleracion
	}

	/*El metodo frenar se implementara en la segunda entrega ya que no se necesita para esta*/
	/*public void testFrenar() {
		auto.acelerar();
		//double aceleracion = auto.getAceleracion();
		
		auto.frenar(); //No esta codificado aun... 
		double esperado = auto.getAceleracion();
		assertEquals(esperado, auto.getAceleracion(),  0.0001);
	}*/

	public void testAgregarComponente() {
		ElementoTaller componente;
		
		componente = new Caja();
		
		try{
			auto.agregarComponente(componente);
		}
		catch (UnableToAddElementToListException noSePuedeAgregar){
			fail("no Se Puede Agregar");
		}
		catch (InvalidMaxMarchaCajaException e){
			fail("Maximo de marcha invalido...");
		}
	}

	public void testRemoverComponente() {
		ElementoTaller componente;
		componente = new Caja();
		
		/*Utilizo lo que ya esta previamente probado*/
			try{
				auto.agregarComponente(componente);
			}
			catch (UnableToAddElementToListException noSePuedeAgregar){
				fail("no Se Puede Agregar");
			}
			catch (InvalidMaxMarchaCajaException e){
				fail("Maximo de marcha invalido...");
			}
		
		/*Esta es la prueba propiamente dicha*/
		try{
			auto.removerComponente(componente);
		}
		catch (UnableToRemoveElementFromListException noSePudoRemoverComponente){
			fail("no Se Pudo Remover Componente");
		}
	}

	public void testObtenerComponente() {
		//ElementoTaller elementoNuevo = new ElementoTaller();
		Caja caja = new Caja();
		ElementoTaller elementoNuevo = null;
		
		/*Utilizo lo que ya esta previamente probado*/
			try{
				auto.agregarComponente(caja);
			}
			catch (UnableToAddElementToListException noSePuedeAgregar){
				fail("no Se Puede Agregar");
			}
			catch (InvalidMaxMarchaCajaException e){
				fail("Maximo de marcha invalido...");
			}
		
		/*Esta es la prueba propiamente dicha*/
		try{
			elementoNuevo = auto.obtenerComponente(caja);
		}
		catch (NoSuchElementException e){
			fail("se genero la excepcion");
		}
		
		assertEquals(elementoNuevo instanceof Caja, true);
	}

	public void testAumentarMarcha() {
		auto.aumentarMarcha();
		assertEquals(2, auto.getMarcha());
		
		auto.aumentarMarcha();
		assertEquals(3, auto.getMarcha());
		
		auto.aumentarMarcha();
		assertEquals(4, auto.getMarcha());
		
		auto.aumentarMarcha();
		assertEquals(5, auto.getMarcha());
		
		auto.aumentarMarcha();
		assertEquals(5, auto.getMarcha());
	}

	public void testDisminuirMarcha() {
		auto.disminuirMarcha();
		assertEquals(1, auto.getMarcha());
		
		auto.disminuirMarcha();
		assertEquals(1, auto.getMarcha());
	}

	public void testGetComponentesAuto() {
		LinkedList <ElementoTaller> lcomponentes = new LinkedList <ElementoTaller>();
		lcomponentes = auto.getComponentesAuto();
		assertEquals(true, lcomponentes.getFirst() instanceof ElementoTaller);
	}

	public void testGetVelocidad() {
		assertEquals(0.0, auto.getVelocidad());
		
		/*--------------SEGUNDO TEST-------------*/
		
		auto.acelerar();
		auto.update(60); /*intervalo de tiempo = 60 mseg.*/
		
		assertEquals(0.23, auto.getVelocidad(), 0.1);
	}

	public void testGetAceleracion() {
		assertEquals(0.0, auto.getAceleracion());
		
		/*--------------SEGUNDO TEST-------------*/
		
		auto.acelerar();
		auto.update(60); /*intervalo de tiempo = 60 mseg.*/
		
		assertEquals(0.003, auto.getAceleracion(), 0.1);
	}

	/*public void testGetPesoTotal() {
		double peso = auto.getPesoTotal();
		assertEquals(890.0, peso);
	}*/

	public void testSetRozamiento() {
		auto.setRozamiento(10.0);  /*Rozamiento de asfalto seco*/
		auto.acelerar();
		auto.update(60); /*intervalo de tiempo = 60 mseg.*/
		double vel = auto.getVelocidad();
		double acel = auto.getAceleracion();
		
		assertEquals(0.23, vel, 0.1);
		assertEquals(0.00392, acel, 0.1);
		
		/*--------------SEGUNDO TEST-------------*/
		auto = new Auto();
		
		auto.setRozamiento(2.5);  /*Rozamiento de hielo mojado*/
		auto.acelerar();
		auto.update(60); /*intervalo de tiempo = 60 mseg.*/
		vel = auto.getVelocidad();
		acel = auto.getAceleracion();
		
		assertEquals(0.22, vel, 0.1);
		assertEquals(0.00388, acel, 0.1);
	}

	public void testGetRPM() {
		
		assertEquals(0.0, auto.getRPM());
		
		/*--------------SEGUNDO TEST-------------*/
		
		auto.acelerar();
		auto.update(60); /*intervalo de tiempo = 60 mseg.*/
		
		assertEquals(485.1, auto.getRPM(), 0.1);
	}

}
